package com.yy.young.ums.service.impl;

import com.yy.young.base.exception.ParameterException;
import com.yy.young.base.exception.YoungBaseException;
import com.yy.young.common.util.CommonUtil;
import com.yy.young.common.util.StringUtils;
import com.yy.young.dal.service.IDataAccessService;
import com.yy.young.dal.util.Page;
import com.yy.young.interfaces.ums.model.Navigate;
import com.yy.young.ums.service.IUmsNavigateService;
import com.yy.young.ums.util.UmsConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by Administrator on 2017/5/8.
 */
@Service("umsNavigateService")
public class UmsNavigateServiceImpl implements IUmsNavigateService {

    @Resource(name="dataAccessService")
    IDataAccessService dataService;

    Logger logger = LoggerFactory.getLogger(UmsNavigateServiceImpl.class);

    @Override
    public List<Map<String, Object>> getNavigateList(Map<String, Object> parameter) throws Exception {
        return dataService.getList(UmsConstants.MAPPER.UMS_NAVIGATE+".getNavigate",parameter);
    }

    @Override
    public List<Map<String, Object>> getNavigatePage(Map<String, Object> parameter,Page page) throws Exception {
        return dataService.getList(UmsConstants.MAPPER.UMS_NAVIGATE+".getNavigate",parameter,page);
    }

    /**
     * 修改资源
     * 1.判断是否修改了父节点
     * 2.如果没有修改父节点,进行正常的修改操作
     * 3.如果父节点被修改,则同步本节点以及本节点下的子节点的'层级'属性
     * @param parameter
     * @return
     * @throws Exception
     */
    @Override
    public int updateNavigate(Map<String, Object> parameter) throws Exception {
        //查询旧数据
        Map<String, Object> old = this.getNavigateById(parameter.get("ID")+"");
        //判断新旧父节点是否一致
        if (StringUtils.equals(old.get("PARENT_ID")+"", parameter.get("PARENT_ID")+"")){//一致
            return dataService.update(UmsConstants.MAPPER.UMS_NAVIGATE+".updateNavigate",parameter);
        }else{//父节点发生变化
            //父节点为空时,默认父节点为虚拟根节点ROOT
            if(StringUtils.isBlank(parameter.get("PARENT_ID")+"")){
                parameter.put("PARENT_ID", "ROOT");
            }

            //当父节点为虚拟根节点时,层级为1
            if ("ROOT".equals(parameter.get("PARENT_ID")+"")){
                parameter.put("NAV_LEVEL", 1);
            }else{
                //父节点为正常节点时,查询新的父节点信息
                Map<String, Object> newParent = this.getNavigateById(parameter.get("PARENT_ID")+"");
                parameter.put("NAV_LEVEL", Integer.parseInt(newParent.get("NAV_LEVEL")+"")+1);//同步节点的层级属性
            }

            //修改节点信息
            dataService.update(UmsConstants.MAPPER.UMS_NAVIGATE+".updateNavigate",parameter);

            //同步节点下所有子节点(包含孙子等更底层节点)的层级属性
            int c = Integer.parseInt(parameter.get("NAV_LEVEL")+"") - Integer.parseInt(old.get("NAV_LEVEL")+"");//计算节点层级的变化量

            //当前变化量不为0时,同步子节点
            if (c != 0){
                logger.info("[资源修改] 当前节点修改前层级为{},修改后层级为{},更新当前节点的所有子节点的层级属性!", old.get("NAV_LEVEL")+"", parameter.get("NAV_LEVEL"));

                //查找需要同步的节点id
                List<String> list = new ArrayList<String>();
                List<String> temp = Arrays.asList(new String[]{parameter.get("ID") + ""});//上一次查出来的节点
                boolean flag = true;
                int n = 0;
                do{
                    //查询上一波查到的节点的子节点
                    List<String> ids = dataService.getList(UmsConstants.MAPPER.UMS_NAVIGATE + ".getNavIdListByPids", temp);
                    if (ids != null && ids.size() > 0){
                        //当查到新子节点时,放入list,继续循环
                        list.addAll(ids);
                        temp = ids;
                        n++;
                    }else{//当已经没有子节点时,将开关关闭,停止循环
                        flag = false;
                    }
                }while(flag && n < 8);//为了防止因为父子节点互相指向对方造成的死循环

                if (n >= 8){
                    logger.error("[资源修改] 查找需要同步的子节点时循环超过8次,极有可能是2个节点互相指向对方为父节点,请检查数据!");
                    throw new Exception("操作失败!请检查资源节点父子关系是否正常!例如当2节点互相指向对方为父节点时会出现此异常!");
                }

                logger.info("[资源修改] 需要同步层级的所有子节点ID为: {}", list);

                if (list != null && list.size() > 0){
                    Map<String, Object> update = new HashMap<String, Object>(4);
                    update.put("ids", list);
                    update.put("CHANGE", c);
                    dataService.update(UmsConstants.MAPPER.UMS_NAVIGATE+".synchronizeNavLevelByIds", update);
                }

            }

            return 1;
        }
    }

    @Override
    public Map<String, Object> getNavigateById(String id) throws Exception {
        Map<String,String> map = new HashMap<String, String>(2);
        map.put("ID", id);
        return (Map<String, Object>)dataService.getObject(UmsConstants.MAPPER.UMS_NAVIGATE+".getNavigate", map);
    }

    /**
     * 删除资源
     * 同时级联删除角色权限中的相关信息
     * @param parameter
     * @return
     * @throws Exception
     */
    @Override
    public int deleteNavigate(Map<String, Object> parameter) throws Exception {
        String idsStr = parameter.get("ids")+"";
        if(StringUtils.isNotBlank(idsStr)){
            String[] idsArr = idsStr.split(",");
            //判断待删除节点的子节点是否为空
            int count = (Integer)dataService.getObject(UmsConstants.MAPPER.UMS_NAVIGATE+".getChildCountByIds", idsArr);
            if(count > 0 ){
                throw new ParameterException("删除失败：请先删除子节点!");
            }
            parameter.put("ids",idsArr);
            this.deleteAuthByNavigateIds(idsArr);//删除关联关系
        }else{
            throw new ParameterException("删除失败：待删除资源编号ids为空!");
        }
        return dataService.delete(UmsConstants.MAPPER.UMS_NAVIGATE+".deleteNavigate",parameter);
    }

    @Override
    public int insertNavigate(Map<String, Object> parameter) throws Exception {
        if(StringUtils.isBlank(parameter.get("ID") + "")){
            parameter.put("ID", CommonUtil.getUUID());//默认ID为UUID
        }
        if(StringUtils.isBlank(parameter.get("PARENT_ID") + "")){
            parameter.put("PARENT_ID",UmsConstants.DEFAULT.ROOT_NAVIGATE);//默认PARENT_ID
        }
        return dataService.insert(UmsConstants.MAPPER.UMS_NAVIGATE+".insertNavigate",parameter);
    }

    @Override
    public List<Navigate> getNavigateByUserId(String userId) throws Exception {
        return dataService.getList(UmsConstants.MAPPER.UMS_NAVIGATE+".getNavigateByUserId",userId);
    }

    @Override
    public List<Map<String, Object>> getNavAuthByRole(String roleId) throws Exception {
        return dataService.getList(UmsConstants.MAPPER.UMS_NAVIGATE+".getNavAuthByRole",roleId);
    }

    @Override
    public List<Navigate> getNavigateAsTreeByUserId(String userId) throws Exception {
        //根据用户ID获取用户角色列表
        //TODO
        //根据权限获取导航
        return null;
    }

    @Override
    public int deleteAuthByNavigateIds(String[] ids) throws Exception {
        logger.info("[角色权限删除] 根据资源id删除权限关系数据,id数组为:{}", ids);
        if(ids != null && ids.length > 0){
            //删除角色权限关系表中的相关数据
            return dataService.delete(UmsConstants.MAPPER.UMS_NAVIGATE+".deleteAuthByNavigateIds", ids);
        }
        return 0;
    }


}
